//
//  UIFont+Typography.swift
//  DesignKit
//
//  Created by Jake Lin on 19/10/20.
//

import UIKit

public extension UIFont {
  static let designKit = DesignKitTypography()

  struct DesignKitTypography {
    public var display1: UIFont {
      if #available(iOS 11.0, *) {
        return scaled(baseFont: .systemFont(ofSize: 42, weight: .semibold), forTextStyle: .largeTitle, maximumFactor: 1.5)
      } else {
        return .systemFont(ofSize: 42, weight: .semibold)
      }
    }

    public var display2: UIFont {
      if #available(iOS 11.0, *) {
        return scaled(baseFont: .systemFont(ofSize: 36, weight: .semibold), forTextStyle: .largeTitle, maximumFactor: 1.5)
      } else {
        return .systemFont(ofSize: 36, weight: .semibold)
      }
    }
    /// 24
    public var title1: UIFont {
      if #available(iOS 11.0, *) {
        return scaled(baseFont: .systemFont(ofSize: 24, weight: .semibold), forTextStyle: .title1)
      } else {
        return .systemFont(ofSize: 24, weight: .semibold)
      }
    }
    /// 20
    public var title2: UIFont {
      if #available(iOS 11.0, *) {
        return scaled(baseFont: .systemFont(ofSize: 20, weight: .medium), forTextStyle: .title2)
      } else {
        return .systemFont(ofSize: 20, weight: .medium)
      }
    }
    /// 16
    public var title3: UIFont {
      if #available(iOS 11.0, *) {
        return scaled(baseFont: .systemFont(ofSize: 16, weight: .semibold), forTextStyle: .title3)
      } else {
        return .systemFont(ofSize: 16, weight: .semibold)
      }
    }
    /// 14
    public var title4: UIFont {
      if #available(iOS 11.0, *) {
        return scaled(baseFont: .systemFont(ofSize: 14, weight: .regular), forTextStyle: .headline)
      } else {
        return .systemFont(ofSize: 14, weight: .regular)
      }
    }

    /// 12
    public var title5: UIFont {
      if #available(iOS 11.0, *) {
        return scaled(baseFont: .systemFont(ofSize: 12, weight: .regular), forTextStyle: .subheadline)
      } else {
        return .systemFont(ofSize: 12, weight: .regular)
      }
    }

    /// 16
    public var bodyBold: UIFont {
      if #available(iOS 11.0, *) {
        return scaled(baseFont: .systemFont(ofSize: 16, weight: .semibold), forTextStyle: .body)
      } else {
        return .systemFont(ofSize: 16, weight: .semibold)
      }
    }

    /// 16
    public var body: UIFont {
      if #available(iOS 11.0, *) {
        return scaled(baseFont: .systemFont(ofSize: 16, weight: .regular), forTextStyle: .body)
      } else {
        return .systemFont(ofSize: 16, weight: .regular)
      }
    }

    /// 14
    public var captionBold: UIFont {
      if #available(iOS 11.0, *) {
        return scaled(baseFont: .systemFont(ofSize: 14, weight: .semibold), forTextStyle: .caption1)
      } else {
        return .systemFont(ofSize: 14, weight: .semibold)
      }
    }

    /// 14
    public var caption: UIFont {
      if #available(iOS 11.0, *) {
        return scaled(baseFont: .systemFont(ofSize: 14, weight: .regular), forTextStyle: .caption1)
      } else {
        return .systemFont(ofSize: 14, weight: .regular)
      }
    }

    public var small: UIFont {
      if #available(iOS 11.0, *) {
        return scaled(baseFont: .systemFont(ofSize: 12, weight: .regular), forTextStyle: .footnote)
      } else {
        return .systemFont(ofSize: 12, weight: .regular)
      }
    }
  }
}

@available(iOS 11.0, *)
private extension UIFont.DesignKitTypography {
  func scaled(baseFont: UIFont, forTextStyle textStyle: UIFont.TextStyle = .body, maximumFactor: CGFloat? = nil) -> UIFont {
    let fontMetrics = UIFontMetrics(forTextStyle: textStyle)

    if let maximumFactor = maximumFactor {
      let maximumPointSize = baseFont.pointSize * maximumFactor
      return fontMetrics.scaledFont(for: baseFont, maximumPointSize: maximumPointSize)
    }
    return fontMetrics.scaledFont(for: baseFont)
  }
}
